package com.hk.service.Impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hk.core.basePageResult.BasePageResult;
import com.hk.domain.Course;
import com.hk.dto.CourseDto;
import com.hk.mapper.CourseMapper;
import com.hk.service.CourseService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.security.SecureRandom;
import java.util.HashSet;
import java.util.Set;

@Service
@Slf4j
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements CourseService {

    @Autowired
    private CourseMapper courseMapper;

    private static final String CHARACTERS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    private static final SecureRandom RANDOM = new SecureRandom();
    private static final int CODE_LENGTH = 8;
    private static final Set<String> generatedCodes = new HashSet<>();

    /**
     * 根据条件查询课程信息
     * @param courseDto
     * @return
     */
    @Override
    public BasePageResult getList(CourseDto courseDto) {
        Page<Course> coursePage = new Page<>(courseDto.getPageNum() , courseDto.getPageSize());
        //获得传入的时间范围
        LambdaQueryWrapper<Course> wrapper = new LambdaQueryWrapper<Course>()
                //课程编号和课程名称支持模糊查询
                .like(StringUtils.isNotEmpty(courseDto.getCode()), Course::getCode, courseDto.getCode())
                .like(StringUtils.isNotEmpty(courseDto.getName()), Course::getName, courseDto.getName())
                //适用人群为精准查询
                .eq(StringUtils.isNotEmpty(courseDto.getApplicablePerson()), Course::getApplicablePerson, courseDto.getApplicablePerson())
                //课程学科为准确查找
                .eq(StringUtils.isNotEmpty(courseDto.getSubject()), Course::getSubject, courseDto.getSubject());
        //判断是否按照开始时间和结束时间查询课程
        Object beginCreatTime = courseDto.getParams().get(BasePageResult.BEGIN_CREATE_TIME);
        Object endCreateTime = courseDto.getParams().get(BasePageResult.END_CREATE_TIME);
        if(ObjectUtils.isNotEmpty(beginCreatTime) && ObjectUtils.isNotEmpty(endCreateTime)){
            wrapper.between(Course::getCreateTime, beginCreatTime, endCreateTime);
        }
        Page<Course> page = super.page(coursePage, wrapper);
        return new BasePageResult(page.getRecords(),(int)page.getTotal());
    }

    /**
     * 添加课程
     * @param course
     */
    @Override
    public void addCourse(Course course) {
        String code = generateUniqueCode();
        course.setCode(code);
        courseMapper.insert(course);
    }

    /**
     * 生成随机课程编号(八位数，数字 ＋ 字母）
     * @return
     */
    private static String generateRandomCode() {
        StringBuilder sb = new StringBuilder(CODE_LENGTH);
        for (int i = 0; i < CODE_LENGTH; i++) {
            int randomIndex = RANDOM.nextInt(CHARACTERS.length());
            sb.append(CHARACTERS.charAt(randomIndex));
        }
        log.info("生成课程编号：{}",sb);
        return sb.toString();
    }

    /**
     * 碰撞测试，保证生成的课程编号不重复
     * @return
     */
    public static synchronized String generateUniqueCode() {
        String code;
        do {
            code = generateRandomCode();
        } while (generatedCodes.contains(code));
        generatedCodes.add(code);
        return code;
    }
}
